package com.liuxinlong.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.liuxinlong.annotation.DataSource;
import com.liuxinlong.api.LDAPAuth;
import com.liuxinlong.auth.Audience;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.DataSourceEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.common.entity.UserHeaderDto;
import com.liuxinlong.modules.dao.BarCardDao;
import com.liuxinlong.modules.dao.ButlerTrainDao;
import com.liuxinlong.modules.dao.DepartmentDao;
import com.liuxinlong.modules.dao.FileManageDao;
import com.liuxinlong.modules.dao.NotificationDao;
import com.liuxinlong.modules.dao.RoleDao;
import com.liuxinlong.modules.dao.StandardDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserFollowDao;
import com.liuxinlong.modules.dao.UserGroupDao;
import com.liuxinlong.modules.dao.UserGroupRelationDao;
import com.liuxinlong.modules.dao.UserMatterDao;
import com.liuxinlong.modules.dao.UserOnlineStatisticsDao;
import com.liuxinlong.modules.dao.UserPostDao;
import com.liuxinlong.modules.dao.UserPostRelationDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.dao.UserStandardPermissionDao;
import com.liuxinlong.modules.dao.UserTeamDao;
import com.liuxinlong.modules.entity.FileManage;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserDepartment;
import com.liuxinlong.modules.entity.UserGroupRelation;
import com.liuxinlong.modules.entity.UserOnlineStatistics;
import com.liuxinlong.modules.entity.UserPost;
import com.liuxinlong.modules.entity.UserPostRelation;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.modules.entity.UserStandardPermission;
import com.liuxinlong.modules.mapper.pdm.WechatUserMapper;
import com.liuxinlong.modules.system.dto.ExportUserDto;
import com.liuxinlong.modules.system.dto.ImportUserDto;
import com.liuxinlong.modules.system.dto.WechatUserDto;
import com.liuxinlong.modules.system.service.RoleRightService;
import com.liuxinlong.modules.system.service.UserService;
import com.liuxinlong.utils.EncryptUtils;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.IPUtils;
import com.liuxinlong.utils.JwtTokenUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.RedisUtils;
import com.liuxinlong.utils.StringCheckUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * 1.0.1 2022-07-11
 * @since 2021-12-28
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private UserTeamDao userTeamDao;

    @Autowired
    private UserPostDao userPostDao;

    @Autowired
    private Audience audience;

    @Autowired
    private RoleRightService roleRightService;

    @Resource
    private RedisUtils redisUtils;

    @Autowired
    private UserGroupRelationDao userGroupRelationDao;

    @Autowired
    private UserPostRelationDao userPostRelationDao;

    @Autowired
    private UserRoleRelationDao userRoleRelationDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Autowired
    private UserGroupDao groupDao;

    @Autowired
    private NotificationDao notificationDao;

    @Autowired
    private UserMatterDao userMatterDao;


    @Autowired
    private UserStandardPermissionDao userStandardPermissionDao;

    @Autowired
    private StandardDao standardDao;

    @Autowired
    private WechatUserMapper wechatUserMapper;

    @Autowired
    private FileManageDao fileManageDao;

    @Autowired
    private BarCardDao barCardDao;

    @Autowired
    private UserFollowDao userFollowDao;

    @Autowired
    private UserOnlineStatisticsDao userOnlineStatisticsDao;

    @Override
    public List<Map<String, Object>> pageUserInfo(Map<String, Object> queryParam) {
        List<User> originalList = userDao.pageUserList(queryParam);
        int startNum = (int) queryParam.get("startNum");
        List<Map<String, Object>> resultList = completeResult(originalList, startNum);
//        log.info("query user info list success!");
        return resultList;
    }

    @Override
    public int getUserCount(Map<String, Object> queryParam) {
        return userDao.getUserCount(queryParam);
    }

    @Override
    @Transactional
    public void addUserInfo(User user, String userRole, String userPost) {
        String userId = SnowFlake.nextIdStr();
        user.setId(userId);
        if (!ObjectUtils.isEmpty(userDao.getUserByAccount(user.getAccount()))) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "存在相同账号！");
        }
        // 用户角色映射
        List<String> roleList = Arrays.asList(userRole.trim().split(","));
        List<UserRoleRelation> roleRelationList = new ArrayList<>(roleList.size());
        for (String roleId : roleList) {
            UserRoleRelation relation = new UserRoleRelation();
            relation.setId(SnowFlake.nextIdStr());
            relation.setUserId(userId);
            relation.setRoleId(roleId);
            roleRelationList.add(relation);
        }
        userRoleRelationDao.insertBatch(roleRelationList);
        user.setPassword(EncryptUtils.AESEncode("123456"));
        // 用户 岗位映射
        if (StringUtils.isNotEmpty(userPost.trim())) {
            List<String> postList = Arrays.asList(userPost.trim().split(","));
            List<UserPostRelation> relationList = new ArrayList<>(postList.size());
            for (String postId : postList) {
                UserPostRelation relation = new UserPostRelation();
                relation.setId(SnowFlake.nextIdStr());
                relation.setUserId(userId);
                relation.setPostId(postId);
                relationList.add(relation);
            }
            userPostRelationDao.insertBatch(relationList);
        }
        userDao.insert(user);
        this.updateCache(user);
    }

    @Override
    @Transactional
    public void updateUserInfo(User user, String userRole, String userPost) {
        String userId = user.getId();
        User oldUser = userDao.selectById(userId);
        if (ObjectUtils.isEmpty(oldUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，用户不存在");
        }
        user.setPassword(oldUser.getPassword());
        user.setStatus(oldUser.getStatus());
        // 用户角色修改
        userRoleRelationDao.deleteByUserId(userId);
        List<String> roleList = Arrays.asList(userRole.trim().split(","));
        List<UserRoleRelation> roleRelationList = new ArrayList<>(roleList.size());
        for (String roleId : roleList) {
            UserRoleRelation relation = new UserRoleRelation();
            relation.setId(SnowFlake.nextIdStr());
            relation.setUserId(userId);
            relation.setRoleId(roleId);
            roleRelationList.add(relation);
        }
        userRoleRelationDao.insertBatch(roleRelationList);

        // 用户组修改
        userPostRelationDao.deleteByUserId(userId);
        if (StringUtils.isNotEmpty(userPost.trim())) {
            List<String> groupList = Arrays.asList(userPost.trim().split(","));
            List<UserPostRelation> relationList = new ArrayList<>(groupList.size());
            for (String postId : groupList) {
                UserPostRelation relation = new UserPostRelation();
                relation.setId(SnowFlake.nextIdStr());
                relation.setUserId(userId);
                relation.setPostId(postId);
                relationList.add(relation);
            }
            userPostRelationDao.insertBatch(relationList);
        }
        userDao.updateById(user);
        user.setPortrait(oldUser.getPortrait());
        this.updateCache(user);
    }

    @Transactional
    @Override
    public void deleteUserInfo(String id) {
        // 逻辑删除，数据保留，便于追溯
        User oldUser = userDao.selectById(id);
        if (ObjectUtils.isEmpty(oldUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，用户不存在");
        }
//        userRoleRelationDao.deleteByUserId(id);
//        userGroupRelationDao.deleteByUserId(id);
        userDao.updateUserStatus(id, 2, oldUser.getLastLoginTime());
    }

    /**
     * 补全数据
     *
     * @param userList 用户数据列表初始数据
     * @param startNum 查询起始数
     * @return 用户数据列表
     */
    private List<Map<String, Object>> completeResult(List<User> userList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (ObjectUtil.isEmpty(userList)) {
            return resultList;
        }
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        Map<String, Map<String, String>> roleMap = roleDao.getRoleMap();
        Map<String, Map<String, String>> teamMap = userTeamDao.getTeamMap();
        Map<String, Map<String, String>> postMap = userPostDao.getUserPostMap();
        int sort = startNum + 1;
        for (User user : userList) {
            Map<String, Object> userMap = ObjectUtils.object2Map(user);
            userMap.put("sort", sort);
            String departmentId = user.getDepartment();
            Map<String, String> departmentInfo = departmentMap.get(departmentId);
            if (ObjectUtil.isNotEmpty(departmentInfo)) {
                userMap.put("departmentName", departmentInfo.get("name"));
            }
            List<UserRoleRelation> roleRelationList = userRoleRelationDao.queryRelationByUserId(user.getId());
            List<String> roleList = roleRelationList.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
            List<String> roleNameList = new ArrayList<>();
            for (String role : roleList) {
                Map<String, String> roleInfo = roleMap.get(role);
                if (ObjectUtil.isNotEmpty(roleInfo)) {
                    roleNameList.add(roleInfo.get("name"));
                }
            }
            userMap.put("role", roleList);
            userMap.put("roleName", roleNameList.toString());
            List<UserPostRelation> postRelationList = userPostRelationDao.queryRelationByUserId(user.getId());
            List<String> postList = postRelationList.stream().map(UserPostRelation::getPostId).collect(Collectors.toList());
            List<String> postNameList = new ArrayList<>();
            for (String post : postList) {
                Map<String, String> postInfo = postMap.get(post);
                if (ObjectUtil.isNotEmpty(postInfo)) {
                    postNameList.add(postInfo.get("name"));
                }
            }
            userMap.put("post", postList);
            userMap.put("postName", StringUtils.strip(postNameList.toString(), "[]"));
            Map<String, String> teamInfo = teamMap.get(user.getTeam());
            if (ObjectUtil.isNotEmpty(teamInfo)) {
                userMap.put("teamName", teamInfo.get("name"));
            }
            String birthday = user.getBirthday();
            if (!StringUtils.isEmpty(birthday)) {
                int age = TimeUtils.age(TimeUtils.formatTime(birthday, TimeFormatConstants.YYYY_MM_DD));
                userMap.put("age", age);
            }
            resultList.add(userMap);
            sort++;
        }
        return resultList;
    }

    @Override
    public Map<String, Object> userLogin(User userInfo) {
        User systemUser = userDao.getUserByAccount(userInfo.getAccount());
        if (ObjectUtils.isEmpty(systemUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "登录失败，用户名或密码不正确！");
        }
//        if (StringUtils.equals(userInfo.getAccount(), "admin") || StringUtils.equals(userInfo.getAccount(), "super") || StringUtils.equals(userInfo.getAccount(), "test001")) {
        // 账号验证在系统内
        if (!StringUtils.equals(EncryptUtils.AESEncode(userInfo.getPassword()), systemUser.getPassword())) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "登录失败，用户名或密码不正确！");
        }
//        } else {
//            // 普通用户验证使用域账号
//            if (!ldapAuth.ady(systemUser.getEmail(), userInfo.getPassword())) {
//                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "登录失败，用户名或密码不正确！");
//            }
//        }
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        userDao.updateUserStatus(systemUser.getId(), 1, currentTime);
        UserOnlineStatistics loginInfo = userOnlineStatisticsDao.getRecord(systemUser.getId(), currentTime.substring(0, 10));
        if (ObjectUtils.isEmpty(loginInfo)) {
            UserOnlineStatistics statistics = new UserOnlineStatistics();
            statistics.setId(SnowFlake.nextIdStr());
            statistics.setUserId(systemUser.getId());
            statistics.setLoginTime(currentTime);
            userOnlineStatisticsDao.insert(statistics);
        }
        Map<String, Object> loginResultMap = new HashMap<>();
        loginResultMap.put("userName", systemUser.getAccount());
        String token = JwtTokenUtils.createJWT(systemUser.getAccount(), systemUser.getAccount(), null, audience);
        redisUtils.setUserCache(systemUser.getId(), token);
        redisUtils.setUserStatus(systemUser.getId(), 1);
        loginResultMap.put("token", token);
        Map<String, Object> authorityMap = roleRightService.queryRoleRightNames(systemUser.getId());
        loginResultMap.put("authority", authorityMap.get("authority"));
        loginResultMap.put("buttonAuthority", authorityMap.get("buttonAuthority"));
//        loginResultMap.put("defaultPass", StringUtils.equals(systemUser.getPassword(), EncryptUtils.AESEncode("123456")) ? "1" : "2");
        return loginResultMap;
    }

    @Override
    public void updatePassword(String oldPass, String newPass) {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (!StringUtils.equals(EncryptUtils.AESEncode(oldPass), current.getPassword())) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，原密码不正确！");
        }

        if (!StringCheckUtils.checkPassword(newPass)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，新密码不符合复杂度规则！");
        }
        userDao.updatePassword(current.getId(), EncryptUtils.AESEncode(newPass));
    }

    @Override
    public void userLogout() {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        redisUtils.deleteUserCache(current.getId());
        redisUtils.setUserStatus(current.getId(), 0);
        userDao.updateUserStatus(current.getId(), 0, null);
    }

    @Override
    public Map<String, Object> getCurrentUser() {
        User user = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("name", user.getName());
        if (StringUtils.isNotEmpty(user.getPortrait())) {
            String currentIp = IPUtils.getCurrentIp();
            FileManage fileManage = fileManageDao.selectById(user.getPortrait());
            resultMap.put("avatar", fileManage.getFilePath().replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
        }

        resultMap.put("sn", user.getSn());
//        resultMap.put("email", user.getEmail());
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("dealUser", user.getId());
        int notifyCount = notificationDao.getNotificationCount(queryParam);
        resultMap.put("notifyCount", notifyCount);
        queryParam.put("status", 0);
        int unreadCount = notificationDao.getNotificationCount(queryParam);
        queryParam.put("dealUser", null);
        queryParam.put("pendingUser", user.getId());
        List<UserRoleRelation> relationList = userRoleRelationDao.queryRelationByUserId(user.getId());
        List<String> roleList = relationList.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
        queryParam.put("roleList", roleList);
        int needCount = userMatterDao.getUserMatterCount(queryParam);
        resultMap.put("unreadCount", unreadCount + needCount);
        return resultMap;
    }

    @Override
    public void offlineUser(String id) {
        redisUtils.deleteUserCache(id);
        redisUtils.setUserStatus(id, 0);
        userDao.updateUserStatus(id, 0, null);
    }

    @Override
    public void blackUser(String id) {

    }

    @Override
    public void resetUser(String id) {
        User user = userDao.selectById(id);
        if (ObjectUtils.isEmpty(user)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "用户不存在");
        }
        String defaultPass = EncryptUtils.AESEncode("123456");
        userDao.updatePassword(id, defaultPass);
    }

    @Override
    public Map<String, Object> queryUserExpInfo() {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", current.getId());
        userInfo.put("name", current.getName());
        userInfo.put("portrait", current.getPortrait());
        userInfo.put("address", current.getAddress());
        if (StringUtils.isNotEmpty(current.getPortrait())) {
            String currentIp = IPUtils.getCurrentIp();
            FileManage fileManage = fileManageDao.selectById(current.getPortrait());
            userInfo.put("fileUrl", fileManage.getFilePath().replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
        }

        return userInfo;
    }

    @Override
    public void updateUserExpInfo(User user) {
        User current = (User) ThreadlocalUtils.getCache("userInfo");
        if (!StringUtils.equals(user.getId(), current.getId()))
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "用户不具备操作权限！");
        this.userDao.updateUserExp(user);
        User dbInfo = userDao.selectById(current.getId());
        user.setName(dbInfo.getName());
//        user.setPost(dbInfo.getPost());
        user.setDepartment(dbInfo.getDepartment());
//        user.setEmail(dbInfo.getEmail());
        user.setSn(dbInfo.getSn());
        updateCache(user);
    }

    @Override
    public Map<String, Object> queryUserBase(String id) {
        Map<String, Object> redisData = redisUtils.getUserInfoCache(id);
        if (!ObjectUtils.isEmpty(redisData)) {
            return redisData;
        }
        User user = userDao.selectById(id);
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("name", user.getName());
        dataMap.put("portrait", user.getPortrait());
        if (StringUtils.isNotEmpty(user.getPortrait())) {
            String currentIp = IPUtils.getCurrentIp();
            FileManage fileManage = fileManageDao.selectById(user.getPortrait());
            dataMap.put("fileUrl", fileManage.getFilePath().replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
        }
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        dataMap.put("departmentName", departmentMap.containsKey(user.getDepartment()) ? departmentMap.get(user.getDepartment()).get("name") : "");
//        dataMap.put("post", user.getPost());
        Map<String, Map<String, String>> roleMap = roleDao.getRoleMap();
        List<UserRoleRelation> roleRelationList = userRoleRelationDao.queryRelationByUserId(id);
        List<String> roleList = roleRelationList.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
        List<String> roleNameList = new ArrayList<>();
        for (String role : roleList) {
            Map<String, String> roleInfo = roleMap.get(role);
            if (ObjectUtil.isNotEmpty(roleInfo)) {
                roleNameList.add(roleInfo.get("name"));
            }
        }
        dataMap.put("roleName", roleNameList.toString());
        dataMap.put("address", user.getAddress());
//        Map<String,Object> queryContributeMap = new HashMap<>();
//        queryContributeMap.put();
//        int  contribute = butlerTrainDao.getTrainInfoCount(queryContributeMap);
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("status", 1);
        queryMap.put("createUser", id);
        int card = barCardDao.getBarCardManageCount(queryMap);
        queryMap.put("userId", id);
        int follow = userFollowDao.getUserFollowCount(queryMap);
        int fans = userFollowDao.getUserFansCount(queryMap);
        dataMap.put("contribute", 1);
        dataMap.put("card", card);
        dataMap.put("follow", follow);
        dataMap.put("fans", fans);
        redisUtils.setUserInfoCache(id, dataMap);
        return dataMap;

    }

    @Override
    public List<String> queryUserGroup(String userId) {
        List<UserGroupRelation> relationList = userGroupRelationDao.queryRelationByUserId(userId);
        List<String> groupList = relationList.stream().map(UserGroupRelation::getGroupId).collect(Collectors.toList());
        return groupList;
    }

    @Override
    @Transactional
    public ImportResp batchAddUser(List<ImportUserDto> dataList) {
        List<Map> failedList = new ArrayList<>();
        // Map<depName,Map<Dep>>
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMapByName();
        // Map<roleName,Map<Role>>
        Map<String, Map<String, String>> roleMap = roleDao.getRoleMapByName();
        // Map<teamName,Map<Group>>
        Map<String, Map<String, String>> teamMap = userTeamDao.getTeamMap();

        List<UserGroupRelation> relationList = new ArrayList<>();
        String defaultPass = EncryptUtils.AESEncode("123456");
        int failedSort = 1;
        for (ImportUserDto userDto : dataList) {
            User dbInfo = userDao.getUserByAccount(userDto.getAccount());
            if (!ObjectUtils.isEmpty(dbInfo)) {
                Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
                userInfo.put("message", "用户已存在！");
                userInfo.put("sort", failedSort);
                failedSort++;
                failedList.add(userInfo);
                continue;
            }
            User user = new User();
            String userId = SnowFlake.nextIdStr();
            user.setId(userId);
            user.setName(userDto.getName());
            user.setSn(userDto.getSn());
            user.setAccount(userDto.getAccount());
            user.setPassword(defaultPass);
            // 匹配用户所在班组
            Map<String, String> depInfo = departmentMap.get(userDto.getDepartment());
            if (ObjectUtils.isEmpty(depInfo)) {
                Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
                userInfo.put("message", "所在班组不存在！");
                userInfo.put("sort", failedSort);
                failedSort++;
                failedList.add(userInfo);
                continue;
            }
            user.setDepartment(depInfo.get("id"));
            // 匹配用户所在小队
            Map<String, String> teamInfo = teamMap.get(userDto.getTeam());
            if (ObjectUtils.isEmpty(teamInfo)) {
                Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
                userInfo.put("message", "所在小队不存在！");
                userInfo.put("sort", failedSort);
                failedSort++;
                failedList.add(userInfo);
                continue;
            }
            user.setTeam(teamInfo.get("id"));
            // 匹配用户角色
            String userRole = userDto.getRole();
            if (userRole.contains(",")) {
                boolean failedFlag = false;
                List<UserRoleRelation> userRoleRelationList = new ArrayList<>();
                for (String role : userRole.split(",")) {
                    Map<String, String> roleInfo = roleMap.get(role);
                    if (ObjectUtils.isEmpty(roleInfo)) {
                        failedFlag = true;
                        break;
                    }
                    UserRoleRelation userRoleRelation = new UserRoleRelation();
                    userRoleRelation.setId(SnowFlake.nextIdStr());
                    userRoleRelation.setUserId(userId);
                    userRoleRelation.setRoleId(roleInfo.get("id"));
                    userRoleRelationList.add(userRoleRelation);
                }
                if (failedFlag) {
                    Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
                    userInfo.put("message", "用户角色不存在！");
                    userInfo.put("sort", failedSort);
                    failedSort++;
                    failedList.add(userInfo);
                    continue;
                }
                userRoleRelationDao.insertBatch(userRoleRelationList);
            } else {
                Map<String, String> roleInfo = roleMap.get(userRole);
                if (ObjectUtils.isEmpty(roleInfo)) {
                    Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
                    userInfo.put("message", "用户角色不存在！");
                    userInfo.put("sort", failedSort);
                    failedSort++;
                    failedList.add(userInfo);
                    continue;
                }
                UserRoleRelation userRoleRelation = new UserRoleRelation();
                userRoleRelation.setId(SnowFlake.nextIdStr());
                userRoleRelation.setUserId(userId);
                userRoleRelation.setRoleId(roleInfo.get("id"));
                userRoleRelationDao.insert(userRoleRelation);
            }

            // 匹配用户


            // 匹配用户分组
//            List<UserGroupRelation> userRelationList = new ArrayList<>();
//            if (!StringUtils.equals(userDto.getGroup1(), "NA")) {
//                Map<String, String> groupInfo = groupMap.get(userDto.getGroup1());
//                if (ObjectUtils.isEmpty(groupInfo)) {
//                    Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
//                    userInfo.put("message", "用户分组1不存在！");
//                    userInfo.put("sort", failedSort);
//                    failedSort++;
//                    failedList.add(userInfo);
//                    continue;
//                }
//                UserGroupRelation relation = new UserGroupRelation();
//                relation.setId(SnowFlake.nextIdStr());
//                relation.setUserId(userId);
//                relation.setGroupId(groupInfo.get("id"));
//                userRelationList.add(relation);
//            }
//            if (!StringUtils.equals(userDto.getGroup2(), "NA")) {
//                Map<String, String> groupInfo = groupMap.get(userDto.getGroup2());
//                if (ObjectUtils.isEmpty(groupInfo)) {
//                    Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
//                    userInfo.put("message", "用户分组2不存在！");
//                    userInfo.put("sort", failedSort);
//                    failedSort++;
//                    failedList.add(userInfo);
//                    continue;
//                }
//                UserGroupRelation relation = new UserGroupRelation();
//                relation.setId(SnowFlake.nextIdStr());
//                relation.setUserId(userId);
//                relation.setGroupId(groupInfo.get("id"));
//                userRelationList.add(relation);
//            }
//            if (!StringUtils.equals(userDto.getGroup3(), "NA")) {
//                Map<String, String> groupInfo = groupMap.get(userDto.getGroup3());
//                if (ObjectUtils.isEmpty(groupInfo)) {
//                    Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
//                    userInfo.put("message", "用户分组3不存在！");
//                    userInfo.put("sort", failedSort);
//                    failedSort++;
//                    failedList.add(userInfo);
//                    continue;
//                }
//                UserGroupRelation relation = new UserGroupRelation();
//                relation.setId(SnowFlake.nextIdStr());
//                relation.setUserId(userId);
//                relation.setGroupId(groupInfo.get("id"));
//                userRelationList.add(relation);
//            }
//            if (!StringUtils.equals(userDto.getGroup4(), "NA")) {
//                Map<String, String> groupInfo = groupMap.get(userDto.getGroup4());
//                if (ObjectUtils.isEmpty(groupInfo)) {
//                    Map<String, Object> userInfo = ObjectUtils.object2Map(userDto);
//                    userInfo.put("message", "用户分组4不存在！");
//                    userInfo.put("sort", failedSort);
//                    failedSort++;
//                    failedList.add(userInfo);
//                    continue;
//                }
//                UserGroupRelation relation = new UserGroupRelation();
//                relation.setId(SnowFlake.nextIdStr());
//                relation.setUserId(userId);
//                relation.setGroupId(groupInfo.get("id"));
//                userRelationList.add(relation);
//            }
//            relationList.addAll(userRelationList);
            userDao.insert(user);
        }
        if (!ObjectUtils.isEmpty(relationList)) {
            userGroupRelationDao.insertBatch(relationList);
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(failedList.size() == 0 ? ReturnCodes.HTTP_SUCCESS.getRetCode() : ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode());
        resp.setRetMessage(failedList.size() == 0 ? "导入用户信息成功" : "导入用户信息部分失败");
        resp.setFailedList(failedList);
        return resp;
    }

    @Override
    public void exportUser(HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("用户信息导出excel.xlsx");
        List<ExportUserDto> userList = userDao.getAllUserList();
        String[] head = {"序号", "账户号码", "工号", "真实姓名", "出生日期", "身份证号", "所在班组", "所在小队", "岗位",
                "入职日期", "在职类型", "在职起始时间", "在职截止时间", "角色", "用户籍贯", "用户地址"};
        data.setHead(head);
        String[][] dataList = new String[userList.size()][head.length];
        int index = 0;
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        Map<String, Map<String, String>> teamMap = userTeamDao.getTeamMap();
        for (ExportUserDto item : userList) {
            dataList[index][0] = String.valueOf(index + 1);
            dataList[index][1] = item.getAccount();
            dataList[index][2] = item.getSn();
            dataList[index][3] = item.getName();
            dataList[index][4] = item.getBirthday();
            dataList[index][5] = item.getIdNumber();
            dataList[index][6] = departmentMap.containsKey(item.getDepartment()) ? departmentMap.get(item.getDepartment()).get("name") : "";
            dataList[index][7] = teamMap.containsKey(item.getTeam()) ? teamMap.get(item.getTeam()).get("name") : "";
            dataList[index][8] = item.getPost();
            dataList[index][9] = item.getJoinDate();
            dataList[index][10] = item.getJobType() == 1 ? "长期" : item.getJobType() == 2 ? "短期" : "临时";
            dataList[index][11] = item.getJobStartTime();
            dataList[index][12] = item.getJobEndTime();

            dataList[index][13] = item.getRoles();
            dataList[index][14] = item.getNativePlace();
            dataList[index][15] = item.getAddress();
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public List<Map<String, Object>> queryStandardPermission(Map<String, Object> queryParam) {
        List<UserStandardPermission> standardPermissionList = userStandardPermissionDao.pageStandardPermissionList(queryParam);
        Map<String, Map<String, String>> standardMap = standardDao.getAllStandardMap();
        List<Map<String, Object>> resultList = new ArrayList<>(standardPermissionList.size());
        int sort = 1;
        for (UserStandardPermission sp : standardPermissionList) {
            Map<String, Object> item = ObjectUtils.object2Map(sp);
            item.put("sort", sort);
            Map<String, String> standardItem = standardMap.get(sp.getStandardId());
            if (ObjectUtils.isEmpty(standardItem)) {
                continue;
            }
            item.put("standardName", standardItem.get("name"));
            item.put("standardSn", standardItem.get("standard_sn"));
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    @Override
    public void updateStandardPermission(UserStandardPermission userStandardPermission) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (StringUtils.isEmpty(userStandardPermission.getId())) {
            userStandardPermission.setCreateUser(currentUser.getId());
            userStandardPermission.setId(SnowFlake.nextIdStr());
            userStandardPermissionDao.insert(userStandardPermission);
            return;
        }
        UserStandardPermission dbInfo = userStandardPermissionDao.selectById(userStandardPermission.getId());
        if (ObjectUtils.isEmpty(dbInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "原权限不存在！");
        }
        dbInfo.setStandardId(userStandardPermission.getStandardId());
        dbInfo.setExpireTime(userStandardPermission.getExpireTime());
        dbInfo.setAttach(userStandardPermission.getAttach());
        userStandardPermissionDao.updateById(dbInfo);
    }

    @Override
    public void deleteStandardPermission(String id) {
        UserStandardPermission dbInfo = userStandardPermissionDao.selectById(id);
        if (ObjectUtils.isEmpty(dbInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "原权限不存在！");
        }
        userStandardPermissionDao.deleteById(id);
    }

    @Override
    @DataSource(DataSourceEnum.PDM)
    public List<WechatUserDto> queryWechatUserList() {
        return wechatUserMapper.pageUserList();
    }

    @Override
    public void syncWechatInfo() {

    }

    @Override
    public List<Map<String, Object>> queryUserOnlineStatistics(Map<String, Object> queryParam) {
        int searchType = (int) queryParam.get("searchType");
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS).substring(0, 10) + " 00:00:00";
        String startTime = "";
        if (searchType == 1) {
            startTime = TimeUtils.getBeforeDay(currentTime, 7, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        } else if (searchType == 2) {
            startTime = TimeUtils.getBeforeDay(currentTime, 30, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        } else if (searchType == 3) {
            startTime = TimeUtils.getBeforeDay(currentTime, 180, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        } else if (searchType == 4) {
            startTime = TimeUtils.getBeforeDay(currentTime, 365, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        }
        queryParam.put("startTime", startTime);
        List<Map<String, Object>> dataList = userOnlineStatisticsDao.getOnlineStatistics(queryParam);
        return dataList;
    }

    @Override
    public ImportResp importUser(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                ImportUserDto user = covertToBean(record);
                return false;
//				try {
//					UserDepartmentDao.addDetail(UserDepartment);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetMessage("导入用户数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入用户数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap<>();
                    item.put("sort", sort);
                    item.put("account", failRecord[0]);
                    item.put("sn", failRecord[1]);
                    item.put("name", failRecord[2]);
                    item.put("birthday", failRecord[3]);
                    item.put("idNumber", failRecord[4]);
                    item.put("department", failRecord[5]);
                    item.put("team", failRecord[6]);
                    item.put("post", failRecord[7]);
                    item.put("joinDate", failRecord[8]);
                    item.put("jobType", failRecord[9]);
                    item.put("jobStartTime", failRecord[10]);
                    item.put("jobEndTime", failRecord[11]);
                    item.put("role", failRecord[12]);
                    item.put("nativePlace", failRecord[13]);
                    item.put("address", failRecord[14]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private ImportUserDto covertToBean(String[] record) {
        ImportUserDto user = new ImportUserDto();
        user.setAccount(record[0].trim());
        user.setSn(record[1].trim());
        user.setName(record[2].trim());
        user.setBirthday(record[3].trim());
        user.setIdNumber(record[4].trim());
        user.setDepartment(record[5].trim());
        user.setTeam(record[6].trim());
        user.setPost(record[7].trim());
        user.setJoinDate(record[8].trim());
        user.setJobType(record[9].trim());
        user.setJobStartTime(record[10].trim());
        user.setJobEndTime(record[11].trim());
        user.setRole(record[12].trim());
        user.setNativePlace(record[13].trim());
        user.setAddress(record[14].trim());
        return user;

    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("用户账号不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 10) {
                addRowError("用户账号长度不能超过10", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("用户姓名不能为空", rowErrors);
        } else {
            if (record[2].trim().length() > 20) {
                addRowError("用户姓名长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[5].trim())) {
            addRowError("用户班组不能为空", rowErrors);
        } else {
            if (record[5].trim().length() > 50) {
                addRowError("用户班组长度不能超过50", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[7].trim())) {
            addRowError("用户岗位不能为空", rowErrors);
        } else {
            if (record[7].trim().length() > 50) {
                addRowError("用户岗位长度不能超过50", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[12].trim())) {
            addRowError("用户角色不能为空", rowErrors);
        } else {
            if (record[12].trim().length() > 50) {
                addRowError("用户角色长度不能超过50", rowErrors);
            }
        }

        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

    /**
     * 修改缓存信息
     *
     * @param user 用户信息
     */
    private void updateCache(User user) {
        UserHeaderDto userHeaderDto = new UserHeaderDto();
        userHeaderDto.setId(user.getId());
        userHeaderDto.setName(user.getName());
//        userHeaderDto.setPost(user.getPost());
//        userHeaderDto.setNickName(user.getAbbreviationName());
        if (!StringUtils.isEmpty(user.getPortrait())) {
            String currentIp = IPUtils.getCurrentIp();
            if (StringUtils.isNotEmpty(user.getPortrait())) {
                FileManage headerFile = fileManageDao.selectById(user.getPortrait());
                if (!ObjectUtils.isEmpty(headerFile)) {
                    String fileUrl = headerFile.getFilePath().replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload");
                    userHeaderDto.setPortrait(fileUrl);
                    userHeaderDto.setFileUrl(fileUrl);
                }
            }
        } else {
            userHeaderDto.setPortrait("");
            userHeaderDto.setFileUrl("");
        }
//        userHeaderDto.setProfile(user.getProfile());
//        userHeaderDto.setEmail(user.getEmail());
        userHeaderDto.setAddress(user.getAddress());
        UserDepartment department = departmentDao.selectById(user.getDepartment());
        userHeaderDto.setDepartmentName(ObjectUtils.isEmpty(department) ? "" : department.getName());
        redisUtils.setUserHeaderCache(user.getId(), userHeaderDto);
        redisUtils.setUserInfoCache(user.getId(), ObjectUtils.object2Map(userHeaderDto));
    }
}
